package com.dhm.adapter.echarts;


import com.dhm.adapter.AbstractChartsMap;
import com.dhm.adapter.Charts;
import com.dhm.bean.EchartsConfig;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.code.*;
import com.github.abel533.echarts.json.GsonOption;
import com.github.abel533.echarts.series.Bar;
import com.github.abel533.echarts.style.LineStyle;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 
 * @author duhongming
 *
 */
public class EchartsDoubleNumLineAdapter<T> extends AbstractChartsMap<String, List<T>> {

	public static final Charts ME = new EchartsDoubleNumLineAdapter();

	/**
	 * 适配器入口
	 * 
	 * @param echartsConfig
	 * @param gsonOption
	 * @param data
	 * @return
	 */
	public GsonOption adapter(EchartsConfig echartsConfig, GsonOption gsonOption, Map<String, List<T>> data) {
		if(data.isEmpty()){
			throw new RuntimeException("Collection no data!");
		}
		gsonOption = tooltipAdapter(gsonOption);
		gsonOption = legendAdapter(gsonOption, data);
		gsonOption = xAxisAdapter(echartsConfig, gsonOption);
		gsonOption = yAxisAdapter(echartsConfig, gsonOption);
		gsonOption = seriesAdapter(echartsConfig, gsonOption, data);
		return gsonOption;
	}

	/**
	 * List<T>转换为List<Object[]>
	 * @param mapList
	 * @return
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("unchecked")
	private List<Object[]> convertListObjectToListObjectArray(List<T> mapList){
		List<Object[]> objList = new ArrayList<Object[]>();
		T tt = mapList.get(0);
		Class clazz = mapList.get(0).getClass();
		if(tt instanceof Map){
			for (Map<String, Object> map : (List<Map<String, Object>>)mapList) {
				Collection<Object> values = map.values();
				List<Object> list = new ArrayList<>(values);
				objList.add(list.toArray());
			}
		}else if(tt instanceof Object[]){
			objList = (List<Object[]>)mapList;
		}else{
			for (T t : mapList) {
				try {
					//内省是Java语言对Bean类属性、事件的一种缺省处理方法。
					BeanInfo tBeanInfo = Introspector.getBeanInfo(t.getClass());
					PropertyDescriptor[] propertyDescriptors = tBeanInfo.getPropertyDescriptors();
					Object[] obj = new Object[2];
					for (PropertyDescriptor property : propertyDescriptors) {
						String key = property.getName();
						Method getter = property.getReadMethod();
						Object value = getter.invoke(t);
						if(key.equals("x")){
							obj[0] = value;
						}else if(key.equals("y")){
							obj[1] = value;
						}
					}
				} catch (IntrospectionException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
//					try {
//						Field[] fs = clazz.getDeclaredFields();
//						Object[] obj = new Object[2];
//						for (int i = 0; i < obj.length; i++) {
//							//设置些属性是可以访问的
//							fs[i].setAccessible(true);
//							//得到此属性的值
//							obj[i] = fs[i].get(t);
//						}
//						objList.add(obj);
//					} catch (IllegalAccessException e) {
//						e.printStackTrace();
//					} catch (SecurityException e) {
//						e.printStackTrace();
//					} catch (IllegalArgumentException e) {
//						e.printStackTrace();
//					}
			}
		}
		return objList;
	}

	/**
	 * tooltipAdapter
	 * 
	 * @param gsonOption
	 * @return
	 */
	private GsonOption tooltipAdapter(GsonOption gsonOption) {
		gsonOption.calculable(true);
		gsonOption.tooltip().axisPointer().show(true).type(PointerType.cross)
				.lineStyle(new LineStyle().type(LineType.dashed).width(1));
		return gsonOption;
	}

	/**
	 * legendAdapter
	 * 
	 * @param gsonOption
	 * @param data
	 * @return
	 */
	private GsonOption legendAdapter(GsonOption gsonOption, Map<String, List<T>> data) {
		// 获取第一个List中的Map中的值
		for (String key : data.keySet()) {
			gsonOption.legend().data(key.replace("y0:", "").replace("y1:", ""));
		}
		return gsonOption;
	}

	/**
	 * x轴配置以及单位配置
	 * 
	 * @param echartsConfig
	 * @param gsonOption
	 * @return
	 */
	private GsonOption xAxisAdapter(EchartsConfig echartsConfig, GsonOption gsonOption) {
		gsonOption.xAxis(new ValueAxis().splitNumber(echartsConfig
				.getSplitNumber())
				//TODO .minInterval(echartsConfig.getMinInterval())
				.type(AxisType.value).name(echartsConfig.getXaxisName()));
		return gsonOption;
	}

	/**
	 * Y轴单位配置
	 * 
	 * @param echartsConfig
	 * @param gsonOption
	 * @return
	 */
	private GsonOption yAxisAdapter(EchartsConfig echartsConfig, GsonOption gsonOption) {
		String[] unitNameArray = echartsConfig.getYaxisName().split(",");
		for (String s : unitNameArray) {
			ValueAxis categoryAxis = new ValueAxis();
			categoryAxis.type(AxisType.value);
			gsonOption.yAxis(categoryAxis.name(s));
		}
		return gsonOption;
	}
	
	/**
	 * Y轴数据处理
	 * 
	 * @param echartsConfig
	 * @param gsonOption
	 * @param axisDataArr
	 * @return
	 */
	private GsonOption seriesAdapter(EchartsConfig echartsConfig, GsonOption gsonOption,
									 Map<String, List<T>> axisDataArr) {
		for (String mapkey : axisDataArr.keySet()) {
			Bar line = new Bar();
			// 显示直线，而不是密密麻麻的点，一点都不好看
			line.name(mapkey.replace("y0:", "").replace("y1:", "")).type(SeriesType.line).symbol(Symbol.none);
			List<T> dataList = axisDataArr.get(mapkey);
			line.data().addAll(convertListObjectToListObjectArray(dataList));
			if (mapkey.startsWith("y0")) {
				line.yAxisIndex(0);
			} else if (mapkey.contains("y1")) {
				line.yAxisIndex(1);
			}
			gsonOption.series(line);
		}
		return gsonOption;
	}

}
